<template>
    <div class="tree-select-container">
      <el-popover
        placement="bottom-start"
        :width="width"
        trigger="click"
        v-model:visible="popoverVisible"
        popper-class="tree-select-popover"
      >
        <template #reference>
          <div class="tree-select-trigger" @click="handleTriggerClick" :class="{ disabled: disabled }">
            <el-input
              readonly
              :model-value="displayValue"
              :placeholder="placeholder"
              :disabled="disabled"
              :clearable="clearable"
              :class="{ 'is-focus': popoverVisible }"
              @clear="handleClear"
            >
              <template #suffix>
                <el-icon :class="{ 'is-reverse': popoverVisible }">
                  <arrow-down />
                </el-icon>
              </template>
            </el-input>
          </div>
        </template>
  
        <div class="tree-select-dropdown">
          <el-input
            v-if="filterable"
            v-model="filterText"
            placeholder="输入关键字进行过滤"
            clearable
            class="filter-input"
          />
          <el-scrollbar>
            <el-tree
              ref="treeRef"
              :data="data"
              :props="defaultProps"
              :node-key="nodeKey"
              :show-checkbox="multiple"
              :check-strictly="checkStrictly"
              :default-expand-all="defaultExpandAll"
              :filter-node-method="filterNode"
              @check="handleCheck"
              @node-click="handleNodeClick"
            >
              <template #default="{ node, data }">
                <span class="tree-node-label">{{ node.label }}</span>
              </template>
            </el-tree>
          </el-scrollbar>
        </div>
      </el-popover>
    </div>
  </template>
  
  <script lang="ts" setup>
  import { ref, computed, watch, nextTick } from 'vue';
  import { ElTree } from 'element-plus';
  import { ArrowDown } from '@element-plus/icons-vue';
  import { TreeNode } from '../types';
  
  type TreeNodeKey = string | number;
  
  /**
   * FormTreeSelect 组件 props 定义
   */
  const props = defineProps<{
    modelValue: TreeNodeKey | TreeNodeKey[];
    data: TreeNode[];
    multiple?: boolean;
    checkStrictly?: boolean;
    filterable?: boolean;
    filterMethod?: (query: string, node: TreeNode) => boolean;
    placeholder?: string;
    disabled?: boolean;
    clearable?: boolean;
    checkOnClickNode?: boolean;
    defaultExpandAll?: boolean;
    width?: number | string;
    nodeKey?: string;
  }>();
  
  /**
   * FormTreeSelect 组件 emit 定义
   */
  const emit = defineEmits<{
    (e: 'update:modelValue', value: TreeNodeKey | TreeNodeKey[]): void;
    (e: 'change', value: TreeNodeKey | TreeNodeKey[]): void;
    (e: 'clear'): void;
  }>();
  
  // 树组件引用
  const treeRef = ref<InstanceType<typeof ElTree> | null>(null);
  
  // 下拉弹出层是否可见
  const popoverVisible = ref(false);
  
  // 过滤文本
  const filterText = ref('');
  
  // 默认节点属性配置
  const defaultProps = {
    children: 'children',
    label: 'label',
    disabled: 'disabled',
  };
  
  // 节点键名
  const nodeKey = computed(() => props.nodeKey || 'id');
  
  // 过滤节点方法
  const filterNode = (value: string, data: TreeNode) => {
    if (!value) return true;
    
    if (props.filterMethod) {
      return props.filterMethod(value, data);
    }
    
    return data.label.includes(value);
  };
  
  // 计算显示文本
  const displayValue = computed(() => {
    if (!props.modelValue) {
      return '';
    }
    
    if (Array.isArray(props.modelValue)) {
      if (props.modelValue.length === 0) {
        return '';
      }
      
      // 获取选中节点的标签
      const selectedLabels = props.modelValue.map(id => {
        const node = findNodeById(props.data, id);
        return node ? node.label : '';
      }).filter(Boolean);
      
      return selectedLabels.join(', ');
    } else {
      const node = findNodeById(props.data, props.modelValue);
      return node ? node.label : '';
    }
  });
  
  // 递归查找节点
  const findNodeById = (nodes: TreeNode[], id: TreeNodeKey): TreeNode | null => {
    for (const node of nodes) {
      if (node.id === id) {
        return node;
      }
      
      if (node.children && node.children.length > 0) {
        const foundChild = findNodeById(node.children, id);
        if (foundChild) {
          return foundChild;
        }
      }
    }
    
    return null;
  };
  
  // 处理节点点击事件
  const handleNodeClick = (data: TreeNode) => {
    if (!props.multiple && (!props.checkOnClickNode || !props.checkStrictly)) {
      const id = data[nodeKey.value] as TreeNodeKey;
      emit('update:modelValue', id);
      emit('change', id);
      popoverVisible.value = false;
    }
  };
  
  // 处理复选框选择事件
  const handleCheck = (data: TreeNode, { checkedKeys, checkedNodes }: any) => {
    if (props.multiple) {
      const checkedValues = checkedNodes.map((node: TreeNode) => node[nodeKey.value]);
      emit('update:modelValue', checkedValues);
      emit('change', checkedValues);
    } else if (props.checkStrictly) {
      // 单选严格模式
      emit('update:modelValue', data[nodeKey.value]);
      emit('change', data[nodeKey.value]);
      popoverVisible.value = false;
    }
  };
  
  // 处理清除事件
  const handleClear = (event: Event) => {
    event.stopPropagation();
    emit('update:modelValue', props.multiple ? [] : '');
    emit('clear');
  };
  
  // 处理触发器点击事件
  const handleTriggerClick = () => {
    if (props.disabled) return;
    popoverVisible.value = !popoverVisible.value;
  };
  
  // 监听过滤文本变化
  watch(filterText, (val) => {
    if (treeRef.value) {
      treeRef.value.filter(val);
    }
  });
  
  // 监听 modelValue 变化，更新树的选中状态
  watch(
    () => props.modelValue,
    (newVal) => {
      nextTick(() => {
        if (!treeRef.value) return;
        
        if (props.multiple && Array.isArray(newVal)) {
          treeRef.value.setCheckedKeys(newVal);
        } else if (!props.multiple && !Array.isArray(newVal) && newVal) {
          // 单选模式，高亮当前节点
          if (treeRef.value.setCurrentKey) {
            treeRef.value.setCurrentKey(newVal);
          }
        }
      });
    },
    { immediate: true }
  );
  
  // 在组件挂载后设置初始选中状态
  onMounted(() => {
    nextTick(() => {
      if (!treeRef.value) return;
      
      if (props.multiple && Array.isArray(props.modelValue)) {
        treeRef.value.setCheckedKeys(props.modelValue);
      } else if (!props.multiple && !Array.isArray(props.modelValue) && props.modelValue) {
        if (treeRef.value.setCurrentKey) {
          treeRef.value.setCurrentKey(props.modelValue);
        }
      }
    });
  });
  </script>
  
  <style scoped>
  .tree-select-container {
    width: 100%;
    position: relative;
  }
  
  .tree-select-trigger {
    width: 100%;
    cursor: pointer;
  }
  
  .tree-select-trigger.disabled {
    cursor: not-allowed;
  }
  
  .tree-select-dropdown {
    max-height: 300px;
  }
  
  .filter-input {
    margin-bottom: 10px;
  }
  
  .tree-node-label {
    font-size: 14px;
  }
  
  :deep(.el-scrollbar) {
    height: 250px;
  }
  
  :deep(.el-input.is-focus .el-input__wrapper) {
    box-shadow: 0 0 0 1px var(--el-color-primary) inset;
  }
  
  :deep(.el-icon.is-reverse) {
    transform: rotate(180deg);
  }
  </style>